package com.miniapp.handler;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.miniapp.handler.exception.BusinessException;
import org.springframework.beans.factory.annotation.Value;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

/**
 *  AES加密类型处理器（兼容PKCS7Padding填充方式）
 * @author author
 * @date 2025-09-01 11:20
 */
public class AesTypeHandler extends AbstractJsonTypeHandler<String> {

    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    /**
     * 16字节偏移量
     */
    private static final String IV = "0102030405060708";


    private SecretKeySpec secretKeySpec;
    private IvParameterSpec ivParameterSpec;

    public AesTypeHandler(@Value("${aes.secret-key}") String secretKey) {
        if (StrUtil.isEmpty(secretKey)) {
            throw new IllegalArgumentException("AES密钥不能为空");
        }
        // 根据编码方式解析密钥
        byte[] keyBytes = decodeKey(secretKey);
        // 验证字节长度
        int byteLength = keyBytes.length;
        if (byteLength != 16 && byteLength != 24 && byteLength != 32) {
            throw new IllegalArgumentException("AES密钥字节长度必须是16、24或32，当前字节长度为：" + byteLength);
        }
        this.secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM);
        this.ivParameterSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 根据配置的编码方式解析密钥
     */
    private byte[] decodeKey(String secretKey) {
        return secretKey.getBytes(StandardCharsets.UTF_8);
    }

    private String encrypt(String content) {
        if (StrUtil.isEmpty(content)) {
            return null;
        }
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] encrypted = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
            return Base64.encode(encrypted);
        } catch (Exception e) {
            throw new BusinessException("AES加密失败: " + e.getMessage());
        }
    }

    private String decrypt(String encryptedContent) {
        if (StrUtil.isEmpty(encryptedContent)) {
            return null;
        }
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] decrypted = cipher.doFinal(Base64.decode(encryptedContent));
            return new String(decrypted, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new BusinessException("AES解密失败: " + e.getMessage());
        }
    }

    @Override
    protected String parse(String json) {
        return decrypt(json);
    }

    @Override
    protected String toJson(String obj) {
        return encrypt(obj);
    }
}



